/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.kungkhies.common.services.kungkhie.parse.xml;

import com.kungkhies.common.services.kungkhie.parse.KungkhieParseException;
import com.kungkhies.common.services.kungkhie.parse.KungkhieParseService;
import com.kungkhies.common.services.kungkhie.validate.KungkhieValidateException;
import com.kungkhies.common.services.kungkhie.validate.xml.KungkhieXmlValidateServiceImpl;
import com.kungkhies.domain.kungkhie.KungkhieSummary;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.InputStream;
import org.springframework.stereotype.Service;

import com.kungkhies.xml.schema.kungkhie.KNodeType;
import com.kungkhies.xml.schema.kungkhie.KungkhieDocument;
import com.kungkhies.xml.schema.kungkhie.impl.KungkhieDocumentImpl;
import com.kungkhies.xml.schema.kungkhie.KungkhieDocument.Factory;
import com.kungkhies.xml.schema.kungkhie.KungkhieType;
import java.io.*;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlOptions;

/**
 *
 * @author clayton
 */
@Service("kungkhieParseService")
public class KungkhieXmlParseServiceXBeansImpl implements KungkhieParseService
{
    private ArrayList parseErrors = new ArrayList();
    private XmlOptions options = new XmlOptions();
    
    public KungkhieXmlParseServiceXBeansImpl(){}

    @Override
    public KungkhieDocument parseKungkhieFromFileLocation(String fileLocation) throws FileNotFoundException, KungkhieParseException
    {
        options = new XmlOptions();
        parseErrors = new ArrayList();
        options.setErrorListener(parseErrors);
        File kungkhieFile = new File(fileLocation);
        KungkhieDocument kungkhieDocument = parseXml(kungkhieFile, options);
        if (!kungkhieDocument.validate(options))
        {
            String parseErrorMessage = null;
            Iterator iter = parseErrors.iterator();
            if (iter.hasNext())
            {
                parseErrorMessage = iter.next().toString();
                System.out.println(">> " + parseErrorMessage + "\n");
            }
            
            throw new KungkhieXmlParseException(parseErrorMessage);
            
        }
        
        return parseXml(kungkhieFile, options);
    }

    @Override
    public KungkhieDocument parseKungkhieFromFile(File kungkhieFile) throws KungkhieParseException
    {
        options = new XmlOptions();
        options.setErrorListener(parseErrors);
        return parseXml(kungkhieFile, options);
    }

    @Override
    public KungkhieDocument parseKungkhieFromString(String kungkhieString) throws KungkhieXmlParseException
    {
        File kungkhieFile = createFileFromString("kungkhie.xml", kungkhieString);

        options = new XmlOptions();
        options.setErrorListener(parseErrors);
        return parseXml(kungkhieFile, options);
    }

    public File createFileFromString(String fileName, String fileContents)
    {
        File file = new File(fileName);
        BufferedWriter out = null;

        try
        {
            out = new BufferedWriter(new FileWriter(fileName));
            out.write(fileContents);
        }
        catch (Exception e)
        {
            Logger.getLogger(KungkhieXmlValidateServiceImpl.class.getName()).log(Level.SEVERE, null, e);
        }
        finally
        {
            try
            {
                out.close();
            }
            catch (IOException ex)
            {
                Logger.getLogger(KungkhieXmlValidateServiceImpl.class.getName()).log(Level.SEVERE, null, ex);
            }
        }

        return file;
    }

    @Override
    public KungkhieDocument parseKungkhieFromStream(InputStream kungkhieStream) throws KungkhieXmlParseException
    {
        File kungkhieFile = new File("kungkhieFile.xml");
        FileOutputStream out = null;

        try
        {
            out = new FileOutputStream(kungkhieFile);
        }
        catch (FileNotFoundException ex)
        {
            Logger.getLogger(KungkhieXmlParseServiceXBeansImpl.class.getName()).log(Level.SEVERE, null, ex);
        }

        int c;

        try
        {

            while ((c = kungkhieStream.read()) != -1)
            {
                out.write(c);
            }

        }
        catch (IOException ex)
        {
            Logger.getLogger(KungkhieXmlParseServiceXBeansImpl.class.getName()).log(Level.SEVERE, null, ex);
        }
        finally
        {
            if (kungkhieStream != null)
            {
                try
                {
                    kungkhieStream.close();
                }
                catch (IOException ex)
                {
                    Logger.getLogger(KungkhieXmlParseServiceXBeansImpl.class.getName()).log(Level.SEVERE, null, ex);
                }
            }

            if (out != null)
            {
                try
                {
                    out.close();
                }
                catch (IOException ex)
                {
                    Logger.getLogger(KungkhieXmlParseServiceXBeansImpl.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }

        options = new XmlOptions();
        options.setErrorListener(parseErrors);
        return parseXml(kungkhieFile, options);

    }

    public KungkhieDocument parseXml(File kungkhieFile, XmlOptions validationOptions) throws KungkhieXmlParseException
    {
        KungkhieDocument xml = null;
        try
        {
            xml = KungkhieDocument.Factory.parse(kungkhieFile, validationOptions);
        }
        catch (XmlException e)
        {
            Iterator iter = parseErrors.iterator();
            if (iter.hasNext())
            {
                
                String errorMessage = (String) iter.next();
                System.out.println(">> " + errorMessage + "\n");
            }
            throw new KungkhieXmlParseException(e.getMessage());
        }
        catch (IOException e)
        {
            throw new KungkhieXmlParseException(e.getMessage());
        }
        return xml;
    }

    public ArrayList getParseErrors()
    {
        return parseErrors;
    }

    public void setParseErrors(ArrayList parseErrors)
    {
        this.parseErrors = parseErrors;
    }
}
